from datetime import date, timedelta
from app.models import ReviewPlan, StudyRecord, PlanConfig,Content
from app.services.ebbinghausReviewScheduler import EbbinghausReviewScheduler
from app.extensions import db

class ReviewPlanService:
    """复习计划管理服务"""
    EBBINGHAUS_INTERVALS = [1, 2, 4, 7, 15, 30, 60, 90]  # 艾宾浩斯间隔天数

    @staticmethod
    def update_review_plan_byKnow(student_id, content_id):
        """更新复习计划
        Args:
            student_id: 学生ID
            content_id: 学习内容ID
        Returns:
            ReviewPlan: 更新或新建的复习计划对象
        """
        # 1. 查询现有复习计划
        existing = ReviewPlan.query.filter_by(
            student_id=student_id,
            content_id=content_id
        ).first()

        today = date.today()
        
        if not existing:
            # 2. 如果复习计划不存在，生成新的复习计划
            new_plan = ReviewPlan(
                content_id=content_id,
                initial_date=today,
                next_review_date=today + timedelta(days=1),
                interval_days=1,
                ebbinghaus_stage=0,
                student_id=student_id,
            )
            db.session.add(new_plan)
            return new_plan.next_review_date
        else:
            # 3. 如果复习计划存在，更新复习计划
            scheduler = EbbinghausReviewScheduler(
                initial_interval_days=existing.interval_days  # 修正参数名
            )
            next_interval = scheduler.next_review_interval(True)

            existing.ebbinghaus_stage += 1
            existing.interval_days = next_interval
            existing.next_review_date = today + timedelta(days=next_interval)
            return existing.next_review_date


    @staticmethod
    def generate_review_plan(cls, record_id: int) -> dict:
        """根据学习记录生成复习计划"""
        record = StudyRecord.query.get(record_id)
        if not record:
            return {'code': 404, 'msg': '学习记录不存在'}
        
        # 获取学习计划配置
        config = PlanConfig.query.filter_by(student_id=record.student_id).first()
        if not config:
            return {'code': 404, 'msg': '未找到学习计划配置'}

        existing = ReviewPlan.query.filter_by(
            student_id=record.student_id,
            content_id=record.content_id
        ).first()

        if existing:
            # 检查是否超过最大重复次数
            if existing.ebbinghaus_stage >= config.max_repeat:
                return {'code': 400, 'msg': '已达最大复习次数'}
            # 更新阶段
            existing.ebbinghaus_stage += 1
            existing.next_review_date = date.today() + timedelta(days=cls.EBBINGHAUS_INTERVALS[existing.ebbinghaus_stage])
        else:
            # 创建新复习计划
            new_plan = ReviewPlan(
                initial_date=date.today(),
                next_review_date=date.today() + timedelta(days=cls.EBBINGHAUS_INTERVALS[0]),
                interval_days=cls.EBBINGHAUS_INTERVALS[0],
                ebbinghaus_stage=0,
                student_id=record.student_id,
                content_id=record.content_id
            )
            db.session.add(new_plan)
        
        db.session.commit()
        return {'code': 200, 'msg': '复习计划已更新'}
    
    @staticmethod
    def get_review_plan(student_id):
        # 获取某个学生的复习计划
        reviewPlans = ReviewPlan.query.filter_by(student_id=student_id).all()

        result = {
            'code': 200,
            'msg': '获取成功',
            'data': []
        }

        for reviewPlan in reviewPlans:
           content = Content.query.filter_by(content_id=reviewPlan.content_id).first()
           if content:
               reviewPlan_dict = reviewPlan.to_dict()
               reviewPlan_dict['title'] = content.title
               result['data'].append(reviewPlan_dict)
        # 按间隔日期倒序排列
        result['data'].sort(key=lambda x: x['interval_days'], reverse=True)
        if not result:
            return {'code': 404, 'msg': '该学生没有复习计划'}
        else:
            return result
        
    @staticmethod
    def delete_review_plan(plan_id):
        reviewPlan = ReviewPlan.query.get(plan_id)
        if reviewPlan:
            db.session.delete(reviewPlan)
            db.session.commit()
            return {'code': 200, 'msg': '删除成功'}
        else:
            return {'code': 404, 'msg': '复习计划不存在'}
    